﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
using MS.InformationManagement.Support.Constants;
using System.Web;
using Microsoft.SharePoint.Taxonomy;


namespace MS.InformationManagement.Support
{
    public static class PeopleHelper
    {
        /// <summary>
        /// Get an array users to populate a peoplepicker control
        /// </summary>
        /// <param name="idUsuarios">List id for users to be loaded in the control</param>
        /// <returns>People picker entity to populate in the control</returns>
        public static ArrayList GetSelectedPeople(IList<int?> idUsuarios, PeopleEditor control)
        {
            ArrayList entityArrayList = new ArrayList();
            foreach (int idUser in idUsuarios)
            {
                PickerEntity entity = new PickerEntity();
                entity.Key = SPContext.Current.Web.SiteUsers.GetByID(idUser).LoginName;
                entity = control.ValidateEntity(entity);
                entityArrayList.Add(entity);
            }
            return entityArrayList;

        }

        public static SPFieldUserValueCollection GetUsersFromPeopleEditor(PeopleEditor control)
        {
            SPFieldUserValueCollection users = new SPFieldUserValueCollection();
            for (int i = 0; i <= control.ResolvedEntities.Count - 1; ++i)
            {
                PickerEntity objEntity = (PickerEntity)control.ResolvedEntities[i];
                users.Add(new SPFieldUserValue(SPContext.Current.Web, SPContext.Current.Web.SiteUsers[objEntity.Key].ID, objEntity.Key));
            }
            return users;
        }

        public static bool IsSiteUser(string userLogin)
        {
            var selectedUser = (from user in SPContext.Current.Web.SiteUsers.OfType<SPUser>()
                                where user.LoginName == userLogin
                                select user).FirstOrDefault();
            return selectedUser != null;
        }

        /// <summary>
        /// Get property from current user profile 
        /// </summary>
        /// <param name="Property">PropertyName</param>
        /// <returns></returns>
        public static string GetPropertyCurrentUserProfile(string propertyName)
        {
            string propertyValue = string.Empty;
            SPServiceContext context = SPServiceContext.GetContext(SPContext.Current.Site);
            UserProfileManager profileManager = new UserProfileManager(context);

            if (profileManager.UserExists(SPContext.Current.Web.CurrentUser.LoginName))
            {
                UserProfile myProfile = profileManager.GetUserProfile(SPContext.Current.Web.CurrentUser.LoginName);

                ProfileValueCollectionBase myProperty = myProfile.GetProfileValueCollection(propertyName);
                if ((myProperty != null) && (myProperty.Value != null))
                {
                    propertyValue = myProperty.Value.ToString();
                }
            }

            return propertyValue;
        }



        /// <summary>
        /// Get property from current user profile 
        /// </summary>
        /// <param name="Property">PropertyName</param>
        /// <returns></returns>
        public static bool UpdatePropertyUserProfile(string propertyName, string propertyValue, string LoginName)
        {
            bool succeed = false;
            SPSite siteColl = SPContext.Current.Site;
            HttpContext tempCtx = HttpContext.Current;

            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite ElevatedsiteColl = new SPSite(siteColl.ID))
                    {
                        SPServiceContext serviceContext = SPServiceContext.GetContext(ElevatedsiteColl);
                        HttpContext.Current = null;
                        UserProfileManager profileManager = new UserProfileManager(serviceContext);
                        if (profileManager.UserExists(LoginName))
                        {
                            UserProfile myProfile = profileManager.GetUserProfile(LoginName);

                            myProfile[propertyName].Value = propertyValue;
                            myProfile.Commit();
                            succeed = true;
                        }
                    }
                });
            }
            catch (Exception ex) { throw ex; }
            finally { HttpContext.Current = tempCtx; }
            return succeed;
        }

        public static bool UpdatePropertyUserProfile(string propertyName, string propertyValue, string LoginName, SPSite site)
        {
            bool succeed = false;
            HttpContext tempCtx = HttpContext.Current;

            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite ElevatedsiteColl = new SPSite(site.ID))
                    {
                        SPServiceContext serviceContext = SPServiceContext.GetContext(ElevatedsiteColl);
                        HttpContext.Current = null;
                        UserProfileManager profileManager = new UserProfileManager(serviceContext);
                        if (profileManager.UserExists(LoginName))
                        {
                            UserProfile myProfile = profileManager.GetUserProfile(LoginName);

                            myProfile[propertyName].Value = propertyValue;
                            myProfile.Commit();
                            succeed = true;
                        }
                    }
                });
            }
            catch (Exception ex) { throw ex; }
            finally { HttpContext.Current = tempCtx; }
            return succeed;
        }


        /// <summary>
        /// Get property from user profile by login
        /// </summary>
        /// <param name="Property">PropertyName</param>
        /// <returns></returns>
        public static string GetPropertyUserProfile(string propertyName, string LoginName, SPWeb currentWeb)
        {

            string propertyValue = string.Empty;
            HttpContext tempCtx = HttpContext.Current;

            try
            {
                SPServiceContext serviceContext = SPServiceContext.GetContext(currentWeb.Site);
                HttpContext.Current = null;
                UserProfileManager profileManager = new UserProfileManager(serviceContext);
                if (profileManager.UserExists(LoginName))
                {
                    UserProfile myProfile = profileManager.GetUserProfile(LoginName);

                    ProfileValueCollectionBase myProperty = myProfile.GetProfileValueCollection(propertyName);
                    if ((myProperty != null) && (myProperty.Value != null))
                    {
                        propertyValue = myProperty.Value.ToString();
                    }
                    else if (myProperty == null) { throw new Exception(string.Format("La propiedad {0} no existe en el perfil del usuario {1}, en el servicio de perfiles de usuario (user profile service) de sharepoint. Contacte al administrador", propertyName, LoginName)); }

                }
            }
            catch (Exception ex) { throw ex; }
            finally { HttpContext.Current = tempCtx; }
            return propertyValue;
        }


        /// <summary>
        /// Get property from user profile by login
        /// </summary>
        /// <param name="Property">PropertyName</param>
        /// <returns></returns>
        public static string GetPropertyUserProfile(string propertyName, string LoginName)
        {

            string propertyValue = string.Empty;
            HttpContext tempCtx = HttpContext.Current;

            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite ElevatedsiteColl = new SPSite(SPContext.Current.Web.Site.ID))
                    {
                        SPServiceContext serviceContext = SPServiceContext.GetContext(ElevatedsiteColl);
                        HttpContext.Current = null;
                        UserProfileManager profileManager = new UserProfileManager(serviceContext);
                        if (profileManager.UserExists(LoginName))
                        {
                            UserProfile myProfile = profileManager.GetUserProfile(LoginName);

                            ProfileValueCollectionBase myProperty = myProfile.GetProfileValueCollection(propertyName);
                            if ((myProperty != null) && (myProperty.Value != null))
                            {
                                propertyValue = myProperty.Value.ToString();
                            }
                            else if (myProperty == null) { throw new Exception(string.Format("La propiedad {0} no existe en el perfil del usuario {1}, en el servicio de perfiles de usuario (user profile service) de sharepoint. Contacte al administrador", propertyName, LoginName)); }
                        }
                        else
                        {
                            throw new Exception(string.Format("El usuario {0} no se encuentra en el servicio de perfiles de usuario (user profile service) de sharepoint. Contacte al administrador.", LoginName.GetUserWithOutDomain()));
                        }
                    }
                });
            }
            catch (Exception ex) { throw ex; }
            finally { HttpContext.Current = tempCtx; }
            return propertyValue;
        }

        /// <summary>
        /// Get a users list that share a property from user profile
        /// </summary>
        /// <param name="PropertyName">PropertyName</param>
        /// <param name="PropertyValue">PropertyValue</param>
        /// <returns></returns>
        public static List<UserProfile> GetUserListByProperty(string PropertyName, string PropertyValue)
        {
            List<UserProfile> usersPropertyValue = new List<UserProfile>();

            SPServiceContext context = SPServiceContext.GetContext(SPContext.Current.Site);
            UserProfileManager profileManager = new UserProfileManager(context);
            foreach (UserProfile currentProfile in profileManager)
            {
                string userName = currentProfile.DisplayName;
                ProfileValueCollectionBase profileValueCollection = currentProfile.GetProfileValueCollection(PropertyName);
                if ((profileValueCollection != null) && (profileValueCollection.Value != null))
                {
                    if (PropertyValue.ToUpper() == profileValueCollection.Value.ToString().ToUpper())
                    {
                        if (currentProfile[GlobalConstants.UP_ACCOUNT].Value.ToString().ToUpper() != SPContext.Current.Web.CurrentUser.LoginName.ToUpper())
                        {
                            usersPropertyValue.Add(currentProfile);
                        }
                    }
                }
            }
            return usersPropertyValue;
        }

        /// <summary>
        /// Get a users list that share a property from user profile
        /// </summary>
        /// <param name="PropertyName">PropertyName</param>
        /// <param name="PropertyValue">PropertyValue</param>
        /// <param name="includeCurrentUser">if set to <c>true</c> [include current user].</param>
        /// <returns></returns>
        public static List<UserProfile> GetUserListByProperty(string PropertyName, string PropertyValue, bool includeCurrentUser)
        {
            List<UserProfile> usersPropertyValue = new List<UserProfile>();

            SPServiceContext context = SPServiceContext.GetContext(SPContext.Current.Site);
            UserProfileManager profileManager = new UserProfileManager(context);
            foreach (UserProfile currentProfile in profileManager)
            {
                string userName = currentProfile.DisplayName;
                ProfileValueCollectionBase profileValueCollection = currentProfile.GetProfileValueCollection(PropertyName);
                if ((profileValueCollection != null) && (profileValueCollection.Value != null))
                {
                    if (PropertyValue.ToUpper() == profileValueCollection.Value.ToString().ToUpper())
                    {
                        if (includeCurrentUser)
                        {
                            usersPropertyValue.Add(currentProfile);
                        }
                        else
                        {
                            if (currentProfile[GlobalConstants.UP_ACCOUNT].Value.ToString().ToUpper() != SPContext.Current.Web.CurrentUser.LoginName.ToUpper())
                            {
                                usersPropertyValue.Add(currentProfile);
                            }
                        }
                    }
                }
            }
            return usersPropertyValue;
        }

        public static Dictionary<string, string> GetUsersByProperty(string PropertyName, string PropertyValue, SPSite site)
        {
            //Dictionary<string, string> users = new Dictionary<string, string>();
            //SPServiceContext context = SPServiceContext.GetContext(SPContext.Current.Site);
            //UserProfileManager profileManager = new UserProfileManager(context);
            //foreach (UserProfile currentProfile in profileManager)
            //{
            //    string userName = currentProfile.DisplayName;
            //    ProfileValueCollectionBase profileValueCollection = currentProfile.GetProfileValueCollection(PropertyName);
            //    if ((profileValueCollection != null) && (profileValueCollection.Value != null))
            //    {
            //        if (PropertyValue == profileValueCollection.Value.ToString())
            //        {
            //            users.Add(currentProfile[GlobalConstants.UP_ACCOUNT].Value.ToString(), currentProfile.DisplayName);
            //        }
            //    }
            //}
            //return users;
            return GetUsersByProperty(PropertyName, PropertyValue, true, site);
        }

        /// <summary>
        /// Get a users list that share a property from user profile
        /// </summary>
        /// <param name="PropertyName">PropertyName</param>
        /// <param name="PropertyValue">PropertyValue</param>
        /// <returns></returns>
        public static Dictionary<string, string> GetUsersByProperty(string PropertyName, string PropertyValue)
        {
            return GetUsersByProperty(PropertyName, PropertyValue, false);
        }

        public static Dictionary<string, string> GetUsersByProperty(string PropertyName, string PropertyValue, bool includeCurrentUser)
        {
            Dictionary<string, string> users = new Dictionary<string, string>();
            SPServiceContext context = SPServiceContext.GetContext(SPContext.Current.Site);
            UserProfileManager profileManager = new UserProfileManager(context);
            foreach (UserProfile currentProfile in profileManager)
            {
                string userName = currentProfile.DisplayName;
                ProfileValueCollectionBase profileValueCollection = currentProfile.GetProfileValueCollection(PropertyName);
                if ((profileValueCollection != null) && (profileValueCollection.Value != null))
                {
                    if (PropertyValue == profileValueCollection.Value.ToString())
                    {
                        users.Add(currentProfile[GlobalConstants.UP_ACCOUNT].Value.ToString().ToUpper(), currentProfile.DisplayName);
                    }
                }
            }
            if (!includeCurrentUser && users.ContainsKey(SPContext.Current.Web.CurrentUser.LoginName.ToUpper())) { users.Remove(SPContext.Current.Web.CurrentUser.LoginName.ToUpper()); }
            return users;
        }

        public static Dictionary<string, string> GetUsersByProperty(string PropertyName, string PropertyValue, bool includeCurrentUser, SPSite site)
        {
            Dictionary<string, string> users = new Dictionary<string, string>();
            SPServiceContext context = SPServiceContext.GetContext(site);
            UserProfileManager profileManager = new UserProfileManager(context);
            foreach (UserProfile currentProfile in profileManager)
            {
                string userName = currentProfile.DisplayName;
                ProfileValueCollectionBase profileValueCollection = currentProfile.GetProfileValueCollection(PropertyName);
                if ((profileValueCollection != null) && (profileValueCollection.Value != null))
                {
                    if (PropertyValue == profileValueCollection.Value.ToString())
                    {
                        users.Add(currentProfile[GlobalConstants.UP_ACCOUNT].Value.ToString().ToUpper(), currentProfile.DisplayName);
                    }
                }
            }
            if (!includeCurrentUser && users.ContainsKey(SPContext.Current.Web.CurrentUser.LoginName.ToUpper())) { users.Remove(SPContext.Current.Web.CurrentUser.LoginName.ToUpper()); }
            return users;
        }

        public static Dictionary<string, string> GetUsers(List<string> sectionCollection, bool includeCurrentUser)
        {
            Dictionary<string, string> users = new Dictionary<string, string>();
            SPServiceContext context = SPServiceContext.GetContext(SPContext.Current.Site);
            UserProfileManager profileManager = new UserProfileManager(context);

            foreach (UserProfile profile in profileManager)
            {
                if (profile[GlobalConstants.UP_DEPARTMENT] != null & profile[GlobalConstants.UP_DEPARTMENT].Value != null)
                {
                    if (sectionCollection.Contains(profile[GlobalConstants.UP_DEPARTMENT].Value.ToString().ToUpper()))
                    {
                        users.Add(profile[GlobalConstants.UP_ACCOUNT].Value.ToString().ToUpper(), string.Format("{0} - {1}", profile[GlobalConstants.UP_DEPARTMENT].Value.ToString(), profile.DisplayName));
                    }
                }
            }

            if (!includeCurrentUser && users.ContainsKey(SPContext.Current.Web.CurrentUser.LoginName.ToUpper())) { users.Remove(SPContext.Current.Web.CurrentUser.LoginName.ToUpper()); }
            return users;
        }

        /// <summary>
        /// Get an spfielduservalue object by loginname
        /// </summary>
        /// <param name="loginName">Loginname for user to query</param>
        /// <returns>SPFieldUserValue object</returns>
        public static SPFieldUserValue GetUserByLoginName(string loginName)
        {
            SPUser selectedUser = SPContext.Current.Web.SiteUsers[loginName];
            return new SPFieldUserValue(SPContext.Current.Web, selectedUser.ID, selectedUser.LoginName);
        }

        public static Dictionary<string, string> GetAllUsers(bool includeDependecy, bool includeCurrentUser)
        {
            Dictionary<string, string> users = new Dictionary<string, string>();
            SPServiceContext context = SPServiceContext.GetContext(SPContext.Current.Site);
            UserProfileManager profileManager = new UserProfileManager(context);

            foreach (UserProfile profile in profileManager)
            {
                if (profile[GlobalConstants.UP_DEPARTMENT] != null & profile[GlobalConstants.UP_DEPARTMENT].Value != null)
                {
                    users.Add(profile[GlobalConstants.UP_ACCOUNT].Value.ToString().ToUpper(),
                        includeDependecy ? string.Format("{0} - {1}", profile[GlobalConstants.UP_DEPARTMENT].Value.ToString(), profile.DisplayName) : profile.DisplayName);
                }
            }

            if (!includeCurrentUser && users.ContainsKey(SPContext.Current.Web.CurrentUser.LoginName.ToUpper())) { users.Remove(SPContext.Current.Web.CurrentUser.LoginName.ToUpper()); }
            return users;
        }

        public static bool UserExist(string LibraryName)
        {
            bool result = false;

            SPServiceContext context = SPServiceContext.GetContext(SPContext.Current.Site);
            UserProfileManager profileManager = new UserProfileManager(context);

            if (profileManager.UserExists(LibraryName))
            {
                result = true;
            }

            return result;
        }

        public static SPUser GetUserById(int userId)
        {
            return SPContext.Current.Web.SiteUsers.GetByID(userId);
        }

        public static string GetUserAccountName(string GuidUserProfile)
        {
            SPServiceContext context = SPServiceContext.GetContext(SPContext.Current.Site);
            UserProfileManager profileManager = new UserProfileManager(context);
            Guid GuidProfile = new Guid(GuidUserProfile);
            UserProfile userProfile = profileManager.GetUserProfile(GuidProfile);
            return userProfile["AccountName"].Value.ToString();
        }

        public static Dictionary<string, string> GetUsers(Dictionary<string, object> properties, bool includeCurrentUser)
        {
            Dictionary<string, string> users = new Dictionary<string, string>();
            SPServiceContext context = SPServiceContext.GetContext(SPContext.Current.Site);
            UserProfileManager profileManager = new UserProfileManager(context);
            foreach (UserProfile currentProfile in profileManager)
            {
                bool equalValues = true;
                string userName = currentProfile.DisplayName;
                //ProfileValueCollectionBase profileValueCollection = currentProfile.GetProfileValueCollection(PropertyName);
                foreach (KeyValuePair<string, object> property in properties)
                {
                    ProfileValueCollectionBase upProperty = currentProfile.GetProfileValueCollection(property.Key);
                    equalValues = upProperty != null && upProperty.Value != null && upProperty.Value.Equals(property.Value);
                }
                if (equalValues) { users.Add(currentProfile[GlobalConstants.UP_ACCOUNT].Value.ToString().ToUpper(), currentProfile.DisplayName); }

            }

            if (!includeCurrentUser && users.ContainsKey(SPContext.Current.Web.CurrentUser.LoginName.ToUpper())) { users.Remove(SPContext.Current.Web.CurrentUser.LoginName.ToUpper()); }
            return users;
        }

        public static Dictionary<string, string> GetUsers(Dictionary<string, object> properties, bool includeCurrentUser, SPSite site)
        {
            Dictionary<string, string> users = new Dictionary<string, string>();
            SPServiceContext context = SPServiceContext.GetContext(site);
            UserProfileManager profileManager = new UserProfileManager(context);
            foreach (UserProfile currentProfile in profileManager)
            {
                bool equalValues = true;
                string userName = currentProfile.DisplayName;
                //ProfileValueCollectionBase profileValueCollection = currentProfile.GetProfileValueCollection(PropertyName);
                foreach (KeyValuePair<string, object> property in properties)
                {
                    ProfileValueCollectionBase upProperty = currentProfile.GetProfileValueCollection(property.Key);
                    equalValues = upProperty != null && upProperty.Value != null && upProperty.Value.Equals(property.Value);
                }
                if (equalValues) { users.Add(currentProfile[GlobalConstants.UP_ACCOUNT].Value.ToString().ToUpper(), currentProfile.DisplayName); }

            }

            if (!includeCurrentUser && users.ContainsKey(SPContext.Current.Web.CurrentUser.LoginName.ToUpper())) { users.Remove(SPContext.Current.Web.CurrentUser.LoginName.ToUpper()); }
            return users;
        }
    }
}
